import os, time, hashlib, datetime
from django.conf import settings
from utils.minio import MinioLib
from django.db import transaction
from django.http import JsonResponse
from rest_framework.views import APIView
from urllib.parse import urlparse, urlunparse
from .models import Attach
from .validate import AddValidate, EditValidate
from .serializers import ListSerializer, DetailSerializer
from utils.utils import responseSuccess, responseError, validateError, serializerJSON, filterFields, MyPaginator

# 列表数据
class ListAPI(APIView):
    def get(self,req):
        queryDict = req.query_params.dict()
        filterDict = filterFields(Attach, queryDict)
        users = Attach.objects.filter(**filterDict)
        paginator = MyPaginator(users, **queryDict)
        serializers = ListSerializer(paginator.object_list, many=True)
        datas = serializerJSON(serializers)
        data = paginator.data(datas)
        return JsonResponse(responseSuccess(data), safe=False)

# 获取详情
class DetailAPI(APIView):
    def get(self, req):
        id = req.query_params.dict().get("id")
        if not id:
            return JsonResponse(responseError('id不能为空'), safe=False)
        serializer = DetailSerializer(Attach.objects.get(pk=id))
        return JsonResponse(responseSuccess(serializer.data), safe=False)
    
# 新增/修改
class SubmitAPI(APIView):
    # 新增
    def post(self,req):
        data = req.data
        edit_id = data.get('id')
        if edit_id:
            role = Attach.objects.get(id=int(edit_id))
            form = EditValidate(role, data=data)
        else:
            form = AddValidate(data=data)
        if form.is_valid():
            if edit_id:
                obj = form.update(role, form.validated_data)
            else:
                obj = form.create(form.validated_data)
            return JsonResponse(responseSuccess(str(obj.pk)), safe=False)
        # 格式化错误信息
        arr = validateError(form.errors)
        return JsonResponse(responseError(arr), safe=False)

# 删除
class RemoveAPI(APIView):
    def post(self,req):
        ids = req.query_params.dict().get('ids')
        if not ids:
            return JsonResponse(responseError('ids不能为空'), safe=False)
        ids = ids.split(',')
        if not Attach.objects.filter(id__in=ids).exists():
            return JsonResponse(responseError('删除对象不存在'), safe=False)
        result = Attach.objects.filter(id__in=ids).delete()
        if result:
            return JsonResponse(responseSuccess(), safe=False)
        return JsonResponse(responseError('删除失败'), safe=False)

# 文件上传
class UploadFileAPI(APIView):
    @transaction.atomic
    def post(self, req):
        files = req.FILES.getlist("file")
        if not files:
            return JsonResponse(responseError('请上传附件'), safe=False)
        datas = []
        for file in files:
            name, extension = os.path.splitext(file.name)
            t = time.strftime("%Y-%m-%d", time.localtime())
            makePath = os.path.join(settings.MEDIA_ROOT, t)
            fileName = hashlib.md5(name.encode('utf-8')).hexdigest() + extension 
            os.path.exists(makePath) or os.makedirs(makePath)
            path = os.path.join(makePath, fileName)
            with open(path,'wb') as f:
                f.write(file.read())
            obj = Attach.objects.create(**{
                "link": f"/{settings.MEDIA_NAME}/{t}/{fileName}",
                "name": fileName,
                "originalName": file.name,
                "extension": extension,
                "attachSize": file.size
            })
            datas.append({
                "url": obj.link
            })
        if len(datas)==1:
            datas = datas[0]
        return JsonResponse(responseSuccess(datas), safe=False)
    
# 上传至minio服务
class UploadFileMinioAPI(APIView):
    # 删除url中的查询参数
    def remove_query_params(self, url):
        parsed_url = urlparse(url)
        return urlunparse(parsed_url._replace(query=''))
    
    def post(self, req):
        files = req.FILES.getlist("file")
        if not files:
            return JsonResponse(responseError('请上传附件'), safe=False)
        
        client = MinioLib()
        datas = []
        for file in files:
            name, extension = os.path.splitext(file.name)
            fileName = hashlib.md5(name.encode('utf-8')).hexdigest() + extension 
            client.put_object(fileName, file, file.size, content_type=file.content_type)
            url = client.presigned_get_object(fileName, expires=datetime.timedelta(seconds=10), response_headers={"response-content-type": file.content_type})
            datas.append({
                "url": self.remove_query_params(url),
                "name": file.name
            })
        if len(datas)==1:
            datas = datas[0]
        return JsonResponse(responseSuccess(datas), safe=False)